const {
	Service
} = require('uni-cloud-router')
const uniID = require('uni-id')
const dbHelper = require('db-helper')
const moment = require('moment-timezone');
moment.prototype.cnZone = function() {
	this.tz("Asia/Shanghai")
	return this
}
const {
	CLOUDURL
} = require('config')
function now() {
	return moment().tz("Asia/Shanghai")
}
const consts = require('consts')
// const redis = uniCloud.redis()
module.exports = class GoodsService extends Service {
	async giveTicketGift({
		skuId,
		storeId,
		memberId,
		count
	}) {
		let transaction = await this.db.startTransaction()
		try {
			let sku = await dbHelper.getById("t3ds-mall-sku", skuId, transaction)
			if (!sku) {
				throw new Error("规格不存在")
			}
			if (!sku.receipts || !sku.receipts.length) {
				throw new Error("不是套票")
			}
			let goods = await dbHelper.getById("t3ds-mall-goods", sku.goods_id)
			if (!goods) {
				throw new Error("商品不存在")
			}
			let store = await dbHelper.getById("t3ds-store", storeId)
			if (!store) {
				throw new Error("门店不存在")
			}
			let member = await dbHelper.getOne("uni-id-users", {
				id: parseInt(memberId)
			})
			if (!member) {
				throw new Error("会员不存在")
			}
			let user = await dbHelper.getById("uni-id-users", this.ctx.auth.uid)
			let gift = {
				storeId,
				skuId,
				uid: member._id,
				count,
				status: 'received',
				receiverId: member._id,
				receiverName: member.nickname,
				receiveTime: Date.now(),
				createTime: Date.now(),
				createBy: user.username
			}
			await dbHelper.insert("t3ds-ticket-gift", gift, transaction)
			let totalCount = await dbHelper.getCount("t3ds-receipts", {})
			var counter = 0
			for (var n = 0; n < count; n++) {
				for (var i = 0; i < sku.receipts.length; i++) {
					let item = sku.receipts[i]
					let deadline
					if (item.deadline.type === 'relative') {
						deadline = moment().tz("Asia/Shanghai").add(item.deadline.value, 'days').hour(
							23).minute(59).second(59).toDate().getTime()
					} else if (item.deadline.type === 'absolute') {
						deadline = moment.tz(item.deadline.value, "Asia/Shanghai").hour(23).minute(59)
							.second(59).toDate().getTime();
					} else {
						deadline = moment().tz("Asia/Shanghai").hour(23).minute(59).second(59).toDate()
							.getTime();
					}
					let t = {
						giftId: gift._id,
						uid: member._id,
						code: `11${member.id}${totalCount + (counter++)}`,
						name: item.name,
						deadline: deadline,
						status: 0,
						goodsId: goods._id,
						skuId: sku._id,
						storeId,
						storeName: store.name,
						createTime: Date.now(),
						source: 'donate'
					}
					await transaction.collection("t3ds-receipts").add(t)
				}
			}
			await transaction.commit()
		} catch (e) {
			console.error(e)
			await transaction.rollback()
			throw e
		}
	}

	async receiveTicketGift({
		giftId
	}) {
		console.log('giftId', giftId)
		let transaction = await this.db.startTransaction()
		try {
			let gift = await dbHelper.getById("t3ds-ticket-gift", giftId, transaction)
			if (!gift) {
				throw new Error("赠品不存在")
			}
			if (gift.status !== 'unreceive') {
				throw new Error("赠品已被领取")
			}
			if (gift.uid && gift.uid != this.ctx.auth.uid) {
				throw new Error("您不能领取该赠品")
			}
			let sku = await dbHelper.getById("t3ds-mall-sku", gift.skuId)
			if (!sku) {
				throw new Error("规格不存在")
			}
			if (!sku.receipts || !sku.receipts.length) {
				throw new Error("不是套票")
			}
			let goods = await dbHelper.getById("t3ds-mall-goods", sku.goods_id)
			if (!goods) {
				throw new Error("商品不存在")
			}
			let member = await dbHelper.getById("uni-id-users", this.ctx.auth.uid)
			let totalCount = await dbHelper.getCount("t3ds-receipts", {})
			var count = 1
			for (var n = 0; n < gift.count; n++) {
				for (var i = 0; i < sku.receipts.length; i++) {
					let item = sku.receipts[i]
					let deadline
					if (item.deadline.type === 'relative') {
						deadline = moment().tz("Asia/Shanghai").add(item.deadline.value, 'days').hour(
							23).minute(59).second(59).toDate().getTime()
					} else if (item.deadline.type === 'absolute') {
						deadline = moment.tz(item.deadline.value, "Asia/Shanghai").hour(23).minute(59)
							.second(59).toDate().getTime();
					} else {
						deadline = moment().tz("Asia/Shanghai").hour(23).minute(59).second(59).toDate()
							.getTime();
					}
					let t = {
						giftId,
						storeId: gift.storeId,
						uid: member._id,
						code: `11${member.id}${totalCount + (count++)}`,
						name: item.name,
						deadline: deadline,
						status: 0,
						goodsId: goods._id,
						skuId: sku._id,
						createTime: Date.now(),
						source: 'donate'
					}
					await transaction.collection("t3ds-receipts").add(t)
				}
			}

			await dbHelper.update("t3ds-ticket-gift", {
				_id: gift._id,
				status: 'received',
				receiverId: member._id,
				receiverName: member.nickname,
				receiveTime: Date.now()
			}, transaction)
			await transaction.commit()
		} catch (e) {
			await transaction.rollback()
			throw e
		}
	}

	async getReceiptNames({
		storeId
	}) {
		let dbCmd = this.db.command
		let $ = dbCmd.aggregate
		let query = [{
			status: 1,
			name: dbCmd.nin(["奇异1", "猫咖2", "奇异2", "猫咖1", "密室", "Vr"])
		}]
		if (storeId) {
			query.push({
				storeId
			})
		} else {
			let isBoss = this.ctx.auth.role.some(item => {
				return item == 'boss'
			})
			let isEmployee = this.ctx.auth.role.some(item => {
				return item == 'employee' || item == 'employee_2'
			})
			if (!isBoss && !isEmployee) {
				return []
			}
			if (isBoss) {
				let goodsRes = await this.db.collection("t3ds-mall-goods").where({
						uid: this.ctx.auth.uid
					})
					.field({
						_id: true
					})
					.get()
				let goodsIds = goodsRes.data.map(item => {
					return item._id
				})
				query.push({
					goodsId: dbCmd.in(goodsIds)
				})
			} else {
				let store = await dbHelper.getOne("t3ds-store", {
					employeeIds: this.ctx.auth.uid
				})
				if (!store) {
					return []
				}
				query.push({
					storeId: store._id
				})
			}
		}

		query = dbCmd.and(query)
		let res = await this.db.collection('t3ds-receipts').aggregate()
			.match(query)
			.group({
				_id: "$name"
			})
			.end()
		// console.log('res', res, query)
		let data = res.data.map(item => {
			return {
				name: item._id
			}
		})
		data.splice(0, 0, {
			name: '全部'
		})
		return data
	}

	async getTicketPackageList({
		storeId,
		pageNum = 1,
		pageSize = 10
	}) {
		let dbCmd = this.db.command
		let $ = dbCmd.aggregate
		let result = {
			total: 0,
			list: []
		}
		let countRes = await this.db.collection("t3ds-mall-sku").aggregate()
			.unwind("$receipts")
			.lookup({
				from: "t3ds-mall-goods",
				localField: "goods_id",
				foreignField: "_id",
				as: "goods"
			})
			.unwind("$goods")
			.match({
				'goods.audit_status': 'passed',
				'goods.store_ids': storeId
			})
			.group({
				_id: {
					_id: "$_id",
					skuName: "$name",
					goodsName: "$goods.name",
					createTime: "$create_time"
				}
			})
			.count('count')
			.end()
		if (!countRes.data.length || !countRes.data[0].count) {
			return result
		}
		result.total = countRes.data[0].count
		let res = await this.db.collection("t3ds-mall-sku").aggregate()
			.unwind("$receipts")
			.lookup({
				from: "t3ds-mall-goods",
				localField: "goods_id",
				foreignField: "_id",
				as: "goods"
			})
			.unwind("$goods")
			.match(dbCmd.and([{
				'goods.store_ids': storeId
			}, dbCmd.or([{
				'goods.is_on_sale': true
			}, {
				'goods.audit_status': 'passed'
			}])]))
			.group({
				_id: {
					_id: "$_id",
					skuName: "$name",
					goodsName: "$goods.name",
					createTime: "$create_time"
				}
			})
			.replaceRoot({
				newRoot: "$_id"
			})
			.lookup({
				from: "t3ds-mall-sku",
				localField: "_id",
				foreignField: "_id",
				as: "sku"
			})
			.unwind("$sku")
			.project({
				skuName: '$skuName',
				goodsName: "$goodsName",
				createTime: 1,
				receipts: "$sku.receipts"
			})
			.sort({
				createTime: -1
			})
			.skip((pageNum - 1) * pageSize)
			.limit(pageSize)
			.end()
		result.list = res.data
		return result
	}

	async clearPosterCache(goodsId) {
		let pageSize = 50
		var pageNum = 1
		var total = 0
		while (true) {
			let res = await this.db.collection('file-cache')
				.where({
					srcUrl: new RegExp(`goods-poster_${goodsId}`)
				})
				.skip((pageNum - 1) * pageSize)
				.limit(pageSize)
				.get()
			if (!res.data.length) {
				break
			}
			var fileIDs = res.data.map(item => {
				return item.fileID
			})
			console.log('fileIDs', fileIDs)
			if (!fileIDs.length) {
				return
			}
			let delFileRes = await uniCloud.deleteFile({
				fileList: fileIDs
			})
			console.log('delFileRes', delFileRes)
			let delCacheCacheRes = await this.db.collection('file-cache')
				.where({
					fileID: this.db.command.in(fileIDs)
				}).remove()
			total += res.data.length
			console.log('delCacheCacheRes', delCacheCacheRes)
		}
		console.log(`成功删除${total}条缓存`)
		return total
	}

	async getNearbyList(userLocation, query, sort, city, pageNum, pageSize) {
		let dbCmd = this.db.command
		let $ = dbCmd.aggregate;
		try {
			let dbQuery = this.db.collection("t3ds-store").aggregate().geoNear({
					distanceField: 'distance',
					spherical: true,
					near: new this.db.Geo.Point(Number(userLocation.longitude), Number(userLocation
						.latitude)),
					query: {
						'region.city.value': city
					}
				})
				.lookup({
					from: "t3ds-mall-goods",
					let: {
						storeId: '$_id'
					},
					pipeline: $.pipeline()
						.match(dbCmd.expr($.in(['$$storeId', '$store_ids'])))
						.done(),
					as: "goods"
				})
				.unwind("$goods")
				.match(query)
				.lookup({
					from: "t3ds-mall-sku",
					let: {
						goodsId: '$goods._id'
					},
					pipeline: $.pipeline()
						.match(dbCmd.expr($.and([
								$.eq(['$goods_id', '$$goodsId']),
								$.eq(['$is_on_sale', true])
							])
						))
						.project({
							price: 1,
							self_buy_reward: 1,
							settlement_price: 1,
							share_reward: 1,
							share_reward3: 1,
							share_reward_old: 1,
							stock: 1,
							unrealSellCount: 1,
							sellCount: 1,
							market_price: 1
						})
						.done(),
					as: 'skus'
				})
				.project({
					_id: '$goods._id',
					name: '$goods.name',
					thumb: '$goods.thumb',
					category_id: '$goods.category_id',
					is_time_limited: '$goods.is_time_limited',
					sale_deadline: '$goods.sale_deadline',
					hit_count: '$goods.hit_count',
					sellInfo: {
						totalSellCount: '$goods.totalSellCount',
						totalStock: '$goods.totalStock',
						price: '$goods.price',
						market_price: '$goods.market_price',
					},
					order_no: '$goods.order_no',
					create_time: '$goods.create_time',
					update_time: '$goods.update_time',
					skus: '$skus',
					distribution: '$goods.distribution',
					distance: '$distance'
				})

			let res
			if (Object.keys(sort).length) {
				res = dbQuery.sort(sort).limit(100).end()
			} else {
				res = await dbQuery.limit(100).end()
			}
			// 一个商品对应多个门店，所以这里要去重，选择最近的门店
			let list = []
			let goodsDic = {}
			res.data.forEach(item => {
				let g = goodsDic[item._id]
				if (!g) {
					goodsDic[item._id] = item
					list.push(item)
				} else {
					let minDistance = Math.min(g.distance, item.distance)
					g.distance = minDistance
				}
			})
			return list || []
		} catch (e) {
			throw e;
		}
	}

	getDistance(loc1, loc2) {
		let la1 = loc1.latitude,
			la2 = loc2.latitude,
			lo1 = loc1.longitude,
			lo2 = loc2.longitude
		var La1 = la1 * Math.PI / 180.0
		var La2 = la2 * Math.PI / 180.0
		var La3 = La1 - La2
		var Lb3 = lo1 * Math.PI / 180.0 - lo2 * Math.PI / 180.0;
		let s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(La3 / 2), 2) + Math.cos(La1) * Math.cos(La2) * Math
			.pow(Math.sin(Lb3 / 2), 2))) * 6378137
		return s
	}

	async getList(query, sort, city, pageNum, pageSize, userLocation) {
		let dbCmd = this.db.command
		let $ = dbCmd.aggregate;
		try {
			let res = await this.db.collection("t3ds-mall-goods").aggregate()
				.match({
					'stores.city': city
				})
				.match(query)
				.lookup({
					from: "t3ds-mall-sku",
					let: {
						goodsId: '$_id'
					},
					pipeline: $.pipeline()
						.match(dbCmd.expr($.and([
								$.eq(['$goods_id', '$$goodsId']),
								$.eq(['$is_on_sale', true])
							])
						))
						.project({
							price: 1,
							self_buy_reward: 1,
							settlement_price: 1,
							share_reward: 1,
							share_reward3: 1,
							share_reward_old: 1,
							stock: 1,
							unrealSellCount: 1,
							sellCount: 1,
							market_price: 1,
							is_on_seckill: 1,
							seckill_status: 1,
							endNowDate: 1,
							startNextDate: 1,
							upDate: 1,
							downDate: 1,
							startDate: 1,
							endDate: 1,
							gapTime: 1,
							buyTime: 1,
							amount: 1,
							amountNow: 1,
						})
						.done(),
					as: 'skus'
				})
				.project({
					_id: '$_id',
					name: '$name',
					thumb: '$thumb',
					category_id: '$category_id',
					is_time_limited: '$is_time_limited',
					sale_deadline: '$sale_deadline',
					hit_count: '$hit_count',
					is_new: '$is_new',
					new_up_deadline: '$new_up_deadline',
					new_down_deadline: '$new_down_deadline',
					sellInfo: {
						totalSellCount: '$totalSellCount',
						totalStock: '$totalStock',
						price: '$price',
						market_price: '$market_price'
					},
					order_no: '$order_no',
					create_time: '$create_time',
					update_time: '$update_time',
					skus: '$skus',
					distribution: '$distribution',
					stores: '$stores'
				})
				.sort(sort)
				.skip((pageNum - 1) * pageSize)
				.limit(pageSize)
				.end()
			if (userLocation) {
				for(let i = 0 ; i < res.data.length ;i++) {
					let minDistance = Number.MAX_SAFE_INTEGER
					let storeId = ""
					res.data[i].stores.forEach(item => {
						if (userLocation) {
							item.distance = this.getDistance(userLocation, {
								longitude: item.location.coordinates[0],
								latitude: item.location.coordinates[1]
							})
						}
						if(minDistance > item.distance) {
							minDistance = item.distance
							storeId = item.store_id
						}
					})
					delete res.data[i].stores
					let storeDetail = {}
					if(storeId) {
						storeDetail = await this.db.collection('t3ds-store').where({
							'_id': storeId
						})
						.field({
							showAddress: true
						})
						.get()
					}
					res.data[i].showAddress = storeDetail.data[0].showAddress
					res.data[i].distance = minDistance
				}
				// res.data.forEach(i => {
				// 	let minDistance = Number.MAX_SAFE_INTEGER
				// 	i.stores.forEach(item => {
				// 		if (userLocation) {
				// 			item.distance = this.getDistance(userLocation, {
				// 				longitude: item.location.coordinates[0],
				// 				latitude: item.location.coordinates[1]
				// 			})
				// 		}
				// 		//minDistance = Math.min(item.distance, minDistance)
				// 	})
				// 	delete i.stores
				// 	i.distance = minDistance
				// })
			}
			return res.data
		} catch (e) {
			throw e;
		}
	}

	async syncGoodsStatus() {
		try {
			let res = await this.db.collection("t3ds-mall-goods").where({
				"is_time_limited": true,
				"is_on_sale": true,
				"sale_deadline": this.db.command.lt(Date.now())
			}).update({
				"is_on_sale": false
			})
			// console.log("商品状态同步完成", res);
		} catch (e) {
			throw e;
		}
	}

	async getGoodsIndex({
		city,
		token,
		userLocation,
		pageNum = 1,
		pageSize = 10
	}) {
		let dbCmd = this.db.command
		let $ = dbCmd.aggregate
		try {
			await this.syncGoodsStatus();
			let result = {
				total: 0,
				list: []
			}
			let countRes = await this.db.collection("t3ds-mall-goods").aggregate()
				.unwind("$store_ids")
				.lookup({
					from: 't3ds-store',
					localField: 'store_ids',
					foreignField: '_id',
					as: 'store'
				})
				.match({
					'is_on_sale': true,
					'display_on_home': true,
					'store.region.city.value': city
				})
				.count('count')
				.end()
			if (!countRes.data || !countRes.data.length || !countRes.data[0].count) {
				return result
			}
			result.total = countRes.data[0].count
			let res = await this.db.collection("t3ds-mall-goods").aggregate()
				.unwind("$store_ids")
				.lookup({
					from: 't3ds-store',
					localField: 'store_ids',
					foreignField: '_id',
					as: 'store'
				})
				.match({
					'is_on_sale': true,
					'display_on_home': true,
					'store.region.city.value': city
				})
				.lookup({
					from: "t3ds-mall-sku",
					let: {
						goodsId: '$_id'
					},
					pipeline: $.pipeline()
						.match(dbCmd.expr($.eq(['$goods_id', '$$goodsId'])))
						.project({
							price: 1,
							self_buy_reward: 1,
							settlement_price: 1,
							share_reward: 1,
							share_reward3: 1,
							share_reward_old: 1,
							stock: 1,
							unrealSellCount: 1,
							sellCount: 1,
							market_price: 1
						})
						.done(),
					as: 'skus'
				})
				.lookup({
					from: "t3ds-mall-sku",
					let: {
						goodsId: '$_id'
					},
					pipeline: $.pipeline()
						.match(dbCmd.expr($.eq(['$goods_id', '$$goodsId'])))
						.group({
							_id: null,
							sellCount: $.sum('$sellCount'),
							unrealSellCount: $.sum('$unrealSellCount'),
							totalStock: $.sum('$stock')
						})
						.addFields({
							totalSellCount: $.add(['$sellCount', '$unrealSellCount'])
						})
						.project({
							_id: 0,
							totalSellCount: 1,
							totalStock: 1
						})
						.done(),
					as: 'sellInfo'
				})
				.lookup({
					from: "t3ds-mall-sku",
					let: {
						goodsId: '$_id'
					},
					pipeline: $.pipeline()
						.match(dbCmd.expr($.eq(['$goods_id', '$$goodsId'])))
						.sort({
							// order: 1,
							price: 1
						})
						.limit(1)
						.project({
							_id: 0,
							price: 1,
							market_price: 1,
							// name: 1,
							stock: 1
						})
						.done(),
					as: 'priceInfo'
				})
				.sort({
					order_no: 1
				})
				.project({
					name: 1,
					display_on_home: 1,
					order_no: 1,
					is_on_sale: 1,
					thumb: 1,
					category_id: 1,
					hit_count: 1,
					create_time: 1,
					update_time: 1,
					is_time_limited: 1,
					sale_deadline: 1,
					skus: 1,
					distribution: 1,
					sellInfo: 1,
					priceInfo: 1,
					storeId: "$store_ids"
				})
				.skip((pageNum - 1) * pageSize)
				.limit(pageSize)
				.end()
			if (userLocation) {
				let storeIds = res.data.map(item => {
					return item.storeId
				})
				let storeRes = await this.db.collection("t3ds-store").aggregate()
					.geoNear({
						distanceField: 'distance',
						spherical: true,
						near: new this.db.Geo.Point(userLocation.longitude, userLocation.latitude),
						query: {
							'_id': dbCmd.in(storeIds)
						}
					})
					.project({
						distance: 1
					})
					.end()
				let storeDic = {}
				storeRes.data.forEach(item => {
					storeDic[item._id] = item
				})
				res.data.forEach(item => {
					item.distance = storeDic[item.storeId].distance
				})
			}
			res.data.forEach(goods => {
				if (goods.name.length > 40) {
					goods.name = goods.name.substring(0, 40)
				}
				let sellInfo = {
					totalStock: 0,
					totalSellCount: 0,
					price: 0,
					market_price: 0,
					stock: 0
				}
				if (goods.sellInfo && goods.sellInfo.length) {
					Object.assign(sellInfo, goods.sellInfo[0])
				}
				if (goods.priceInfo && goods.priceInfo.length) {
					Object.assign(sellInfo, goods.priceInfo[0])
				}
				goods.sellInfo = sellInfo
				delete goods.priceInfo
			})
			if (token) {
				let payload = await uniID.checkToken(token)
				if (payload.code === 0) {
					let member = payload.userInfo
					let gradeSetting = await dbHelper.getOne("t3ds-share-expert-grade", {
						value: member.shareGrade
					})
					res.data.forEach(goods => {
						if (goods.distribution) {
							var maxShareReward = 0
							var maxShareReward2 = 0
							var maxBuyReward = 0
							goods.skus.forEach(sku => {
								let profit = sku.price - sku.settlement_price;
								let shareReward = sku.share_reward[gradeSetting.value + ""];
								if (shareReward == undefined || shareReward < 0) {
									sku.shareReward = Math.round(gradeSetting.share_reward /
										100 * profit /
										100) * 100;
								} else {
									sku.shareReward = Math.round(shareReward / 100 *
										profit / 100) * 100;
								}
								maxShareReward = Math.max(maxShareReward, sku.shareReward)
								if (sku.share_reward2 == undefined || sku.share_reward2 <
									0) {
									sku.shareReward2 = Math.round(gradeSetting
										.share_reward2 / 100 * profit /
										100) * 100;
								}
								maxShareReward2 = Math.max(maxShareReward2, sku
									.shareReward2)
								if (gradeSetting.value !== 0) {
									let buyReward = sku.self_buy_reward[gradeSetting.value +
										''];
									if (buyReward == undefined || buyReward < 0) {
										sku.buyReward = Math.round(gradeSetting
											.self_buy_reward / 100 *
											profit / 100) * 100;
									} else {
										sku.buyReward = Math.round(buyReward / 100 *
											profit / 100) * 100
									}
									maxBuyReward = Math.max(maxBuyReward, sku.buyReward)
								}
							})
							Object.assign(goods.sellInfo, {
								maxShareReward,
								maxShareReward2,
								maxBuyReward
							})
						}
					})
				}
			}
			res.data.forEach(goods => {
				delete goods.skus
			})
			result.list = res.data
			return result
		} catch (e) {
			throw e
		}
	}

	async getGoodsListPub({
		pageNum = 1,
		pageSize = 10,
		city = "4201",
		filter,
		order,
		keyword,
		userLocation,
		token
	}) {
		try {
			await this.syncGoodsStatus();
			let query = {
				'goods.is_on_sale': true
			}
			let query1 = {
				'is_on_sale': true
			}
			if (filter) {
				if (filter.categoryId) {
					query['goods.category_id'] = filter.categoryId;
					query1['category_id'] = filter.categoryId;
				}
				if (filter.displayOnHome) {
					query['goods.display_on_home'] = filter.displayOnHome;
					query1['display_on_home'] = filter.displayOnHome;
				}
			}
			if (keyword) {
				query['goods.name'] = new RegExp(`${keyword}+`, 'i');
				query1['name'] = new RegExp(`${keyword}+`, 'i');
			}
			// console.log("query", JSON.stringify(query));
			let sort = {};
			if (order) {
				if (order.hitCount) {
					sort['hit_count'] = order.hitCount === "asc" ? 1 : -1;
				}
				if (order.price) {
					sort['sellInfo.price'] = order.price === "asc" ? 1 : -1;
				}
				if (order.sales) {
					sort['sellInfo.totalSellCount'] = order.sales === "asc" ? 1 : -1
				}
				if (order.orderNo) {
					sort['order_no'] = order.orderNo === "asc" ? 1 : -1;
				}
			}
			if (!Object.keys(sort).length && (!order || !order.distance)) {
				sort.update_time = -1;
				sort.create_time = -1;
			}
			// console.log("sort", sort);
			let dbCmd = this.db.command
			let $ = dbCmd.aggregate;
			let result = {
				total: 0,
				list: []
			}
			if (order && order.distance && userLocation) {
				let countRes = await this.db.collection("t3ds-store").aggregate().geoNear({
						distanceField: 'distance',
						spherical: true,
						near: new this.db.Geo.Point(Number(userLocation.longitude), Number(userLocation
							.latitude)),
						query: {
							'region.city.value': city
						}
					})
					.lookup({
						from: "t3ds-mall-goods",
						let: {
							storeId: '$_id'
						},
						pipeline: $.pipeline()
							.match(dbCmd.expr($.in(['$$storeId', '$store_ids'])))
							.done(),
						as: 'goods'
					})
					.unwind({
						path: "$goods"
					})
					.match(query)
					.project({
						_id: 0,
						goods: 1
					})
					.replaceRoot({
						newRoot: '$goods'
					})
					.group({
						_id: '$_id'
					})
					.count('count')
					.end();
				if (!countRes.data.length) {
					return result
				}
				result.total = countRes.data[0].count
				result.list = await this.getNearbyList(userLocation, query, sort, city, pageNum, pageSize)
			} else {
				let countRes = await this.db.collection("t3ds-mall-goods")
					.where(query1)
					.count()
				if (!countRes.total) {
					return result
				}
				result.total = countRes.total;
				result.list = await this.getList(query1, sort, city, pageNum, pageSize, userLocation);
			}
			if (token) {
				let payload = await uniID.checkToken(token)
				if (payload.code === 0) {
					let member = payload.userInfo
					let gradeSetting = await dbHelper.getOne("t3ds-share-expert-grade", {
						value: member.shareGrade
					})
					result.list.forEach(goods => {
						if (goods.distribution) {
							var maxShareReward = 0
							var maxShareReward2 = 0
							var maxBuyReward = 0
							goods.skus.forEach(sku => {
								let profit = sku.price - sku.settlement_price;
								let shareReward = sku.share_reward[gradeSetting.value + ""];
								if (shareReward == undefined || shareReward < 0) {
									sku.shareReward = Math.round(gradeSetting.share_reward /
										100 * profit /
										100) * 100;
								} else {
									sku.shareReward = Math.round(shareReward / 100 *
										profit / 100) * 100;
								}
								maxShareReward = Math.max(maxShareReward, sku.shareReward)
								if (sku.share_reward2 == undefined || sku.share_reward2 <
									0) {
									sku.shareReward2 = Math.round(gradeSetting
										.share_reward2 / 100 * profit /
										100) * 100;
								}
								maxShareReward2 = Math.max(maxShareReward2, sku
									.shareReward2)
								if (gradeSetting.value !== 0) {
									let buyReward = sku.self_buy_reward[gradeSetting.value +
										''];
									if (buyReward == undefined || buyReward < 0) {
										sku.buyReward = Math.round(gradeSetting
											.self_buy_reward / 100 *
											profit / 100) * 100;
									} else {
										sku.buyReward = Math.round(buyReward / 100 *
											profit / 100) * 100
									}
									maxBuyReward = Math.max(maxBuyReward, sku.buyReward)
								}
							})
							Object.assign(goods.sellInfo, {
								maxShareReward,
								maxShareReward2,
								maxBuyReward
							})
						}
					})
				}
			}
			result.list.forEach(goods => {
				delete goods.skus
			})
			return result
		} catch (e) {
			console.error(e)
			throw e
		}
	}

	//弃用
	async getGoodsList({
		keyword,
		city,
		order,
		uid,
		channel,
		pageNum = 1,
		pageSize = 10,
		isOnSell,
		auditStatus, //waiting待审核，passed审核通过 rejected审核未通过
		isTimeLimited,
		inWarehouse,
	}) {
		let dbCmd = this.db.command
		let result = {
			total: 0,
			list: []
		}
		let query = {};
		if (uid) {
			query.uid = uid
		}
		if (channel) {
			if (channel === 'self') {
				query.channel = dbCmd.eq(channel).or(dbCmd.exists(false))
			} else {
				query.channel = channel
			}
		}
		if (keyword) {
			query.name = new RegExp(keyword);
		}
		//
		if (isOnSell != null) {
			query.is_on_sale = isOnSell
		}
		if (auditStatus != null) {
			query.audit_status = auditStatus
		}
		if (isTimeLimited != null) {
			query.is_time_limited = true
			query.sale_deadline = dbCmd.lt(Date.now())
		}
		if (inWarehouse != null) {
			if (inWarehouse == false) {
				query.in_warehouse = dbCmd.eq(inWarehouse).or(dbCmd.exists(false))
			} else {
				query.in_warehouse = true
			}
		}
		//
		let sort = {};
		if (order && order.sellCount && (order.sellCount == 1 || order.sellCount == -1)) {
			sort["sellInfo.sellCount"] = parseInt(order.sellCount);
		}
		if (order && order.stock && (order.stock == 1 || order.stock == -1)) {
			sort["sellInfo.stock"] = parseInt(order.stock);
		}
		if (!Object.keys(sort).length) {
			sort = {
				"update_time": -1,
				"create_time": -1
			}
		}
		if (city) {
			let merchantRes = await this.db.collection('uni-id-users').where({
				'city': city,
				'role': 'boss'
			}).field({
				_id: true
			}).limit(1000).get()
			console.log('merchantRes', merchantRes)
			let ids = merchantRes.data.map(item => {
				return item._id
			})
			if (!ids.length) {
				return result
			}
			if (ids.length) {
				query.uid = dbCmd.in(ids)
			}
		}
		const $ = dbCmd.aggregate;
		try {
			if (pageNum == 1) {
				let total = await dbHelper.getCount("t3ds-mall-goods", query);
				if (!total) {
					return result;
				}
				result.total = total;
			}
			let res = await this.db.collection("t3ds-mall-goods").aggregate()
				.match(query)
				.lookup({
					from: "t3ds-mall-sku",
					let: {
						goodsId: "$_id"
					},
					pipeline: $.pipeline()
						.match(dbCmd.expr($.eq(["$goods_id", "$$goodsId"])))
						.group({
							_id: "$goods_id",
							sellCount: $.sum("$sellCount"),
							stock: $.sum("$stock")
						})
						.done(),
					as: "sellInfo"
				})
				.sort(sort)
				.project({
					_id: 1,
					name: 1,
					thumb: 1,
					is_on_sale: 1,
					sellInfo: 1,
					channel: 1,
					audit_status: 1,
					in_warehouse: 1,
					module_ids: 1
				})
				.skip((pageNum - 1) * pageSize)
				.limit(pageSize)
				.end()
			res.data.forEach(item => {
				if (item.sellInfo.length) {
					item.sellInfo = item.sellInfo[0];
				} else {
					item.sellInfo = {
						sellCount: 0,
						stock: 0
					}
				}
			})
			result.list = res.data;
			return result;
		} catch (e) {
			console.error("获取商品列表遇到错误", e);
			throw e
		}
	}

	async getSoldGoodsList({
		startDate,
		endDate,
		keyword
	}) {
		let dbCmd = this.db.command
		let $ = dbCmd.aggregate
		let query = {
			status: dbCmd.gt(1).and(dbCmd.lt(6)),
			type: 'goods',
			'items.settlement_price': dbCmd.exists(true)
		};
		if (startDate && endDate) {
			query.pay_time = dbCmd.gt(startDate).and(dbCmd.lt(endDate));
		} else if (endDate) {
			query.pay_time = dbCmd.lt(endDate);
		} else if (startDate) {
			query.pay_time = dbCmd.gt(startDate);
		}
		if (keyword) {
			query["items.goods_name"] = new RegExp(keyword);
		}
		let result = {
			total: 0,
			list: []
		}
		let totalRes = await this.db.collection("t3ds-order").aggregate()
			.match(query)
			.group({
				_id: {
					goodsId: "$items.goods_id"
				},
			})
			.count("total")
			.end();
		if (!totalRes.data || !totalRes.data.length) {
			return result;
		}
		result.total = totalRes.data[0].total;
		let res = await this.db.collection("t3ds-order").aggregate()
			.match(query)
			.unwind("$items")
			.group({
				_id: {
					goodsId: "$items.goods_id"
				},
			})
			.lookup({
				from: "t3ds-mall-goods",
				let: {
					goodsId: "$_id.goodsId"
				},
				pipeline: $.pipeline()
					.match(dbCmd.expr($.eq(["$_id", "$$goodsId"])))
					.project({
						"_id": 1,
						"name": 1,
						"thumb": 1
					})
					.done(),
				as: "goods"
			})
			.unwind("$goods")
			.replaceRoot({
				newRoot: "$goods"
			})
			.end();
		result.list = res.data
		return result
	}

	async getGoodsProfit({
		goodsId,
		startDate,
		endDate
	}) {
		let dbCmd = this.db.command
		let $ = dbCmd.aggregate
		let query = {
			status: dbCmd.gt(1).and(dbCmd.lt(6)),
			type: 'goods',
			'items.settlement_price': dbCmd.exists(true)
		};
		if (startDate && endDate) {
			query.pay_time = dbCmd.gt(startDate).and(dbCmd.lt(endDate))
		} else if (endDate) {
			query.pay_time = dbCmd.lt(endDate)
		} else if (startDate) {
			query.pay_time = dbCmd.gt(startDate)
		}
		query["items.goods_id"] = goodsId
		let totalRes = await this.db.collection("t3ds-order").aggregate()
			.match(query)
			.group({
				_id: {
					goodsId: "$items.goods_id"
				},
			})
			.count("total")
			.end();
		if (!totalRes.data || !totalRes.data.length) {
			return {
				profit: 0,
				sellCount: 0,
				stock: 0
			}
		}
		let res = await this.db.collection("t3ds-order").aggregate()
			.match(query)
			.unwind("$items")
			.lookup({
				from: "t3ds-account-log",
				let: {
					orderId: "$_id"
				},
				pipeline: $.pipeline()
					.match(dbCmd.expr($.and([
						$.eq(["$orderId", "$$orderId"]),
						$.in(["$tradeType", [1, 2, 3, 4, 7, 8]])
					])))
					.group({
						_id: null,
						income: $.sum("$income")
					})
					.done(),
				as: "brokerageInfo"
			})
			.unwind("$brokerageInfo")
			.project({
				goodsId: "$items.goods_id",
				count: "$items.count",
				totalFee: "$total_fee",
				brokerage: "$brokerageInfo.income",
				settlement: $.multiply(["$items.settlement_price", "$items.count"])
			})
			.project({
				goodsId: "$goodsId",
				count: "$count",
				totalFee: "$totalFee",
				cost: $.add(["$brokerage", "$settlement"])
			})
			.project({
				goodsId: "$goodsId",
				count: "$count",
				profit: $.subtract(["$totalFee", "$cost"])
			})
			.group({
				_id: "$goodsId",
				profit: $.sum("$profit"),
				sellCount: $.sum("$count")
			})
			.project({
				goodsId: "$_id",
				profit: 1,
				sellCount: 1,
				_id: 0
			})
			.lookup({
				from: "t3ds-mall-sku",
				let: {
					goodsId: "$goodsId"
				},
				pipeline: $.pipeline()
					.match(dbCmd.expr($.eq(["$goods_id", "$$goodsId"])))
					.group({
						_id: null,
						sellCount: $.sum("$sellCount"),
						stock: $.sum("$stock")
					})
					.done(),
				as: "sellInfo"
			})
			.unwind("$sellInfo")
			.project({
				profit: 1,
				sellCount: 1,
				totalSellCount: "$sellInfo.sellCount",
				stock: "$sellInfo.stock"
			})
			.end();
		return res.data
	}

	async getGoodsProfitList({
		startDate,
		endDate,
		order,
		keyword,
		city
	}) {
		let result = {
			total: 0,
			totalProfit: 0,
			totalFee: 0,
			list: []
		}
		let dbCmd = this.db.command
		let $ = dbCmd.aggregate
		let merchantRes = await this.db.collection("uni-id-users").where({
			city,
			role: 'boss'
		}).limit(1000).field({
			_id: true
		}).get()
		if (!merchantRes.data.length) {
			return result
		}
		let merchantIds = merchantRes.data.map(item => {
			return item._id
		})
		let goodsRes = await this.db.collection("t3ds-mall-goods").where({
			uid: dbCmd.in(merchantIds)
		}).limit(1000).field({
			_id: true
		}).get()
		if (!goodsRes.data.length) {
			return result
		}
		var goodsIds = goodsRes.data.map(item => {
			return item._id
		})
		let query = {
			status: dbCmd.gt(2).and(dbCmd.lt(10)),
			type: 'goods',
			'items.settlement_price': dbCmd.exists(true),
			'items.goods_id': dbCmd.in(goodsIds)
		};
		if (startDate && endDate) {
			query.pay_time = dbCmd.gte(startDate).and(dbCmd.lte(endDate));
		} else if (endDate) {
			query.pay_time = dbCmd.lte(endDate);
		} else if (startDate) {
			query.pay_time = dbCmd.gte(startDate);
		}
		if (keyword) {
			query["items.goods_name"] = new RegExp(keyword);
		}
		if (!order) {
			order = -1
		}
		let totalRes = await this.db.collection("t3ds-order").aggregate()
			.match(query)
			.group({
				_id: {
					goodsId: "$items.goods_id"
				},
			})
			.count("total")
			.end();
		if (!totalRes.data || !totalRes.data.length) {
			return result;
		}
		result.total = totalRes.data[0].total;
		let res = await this.db.collection("t3ds-order").aggregate()
			.match(query)
			.unwind("$items")
			.lookup({
				from: "t3ds-account-log",
				let: {
					orderId: "$_id"
				},
				pipeline: $.pipeline()
					.match(dbCmd.expr($.and([
						$.eq(["$orderId", "$$orderId"]),
						$.in(["$tradeType", [1, 2, 3, 4, 7, 8, -5]])
					])))
					.group({
						_id: null,
						income: $.sum("$income")
					})
					.done(),
				as: "brokerageInfo"
			})
			// // 退款扣除的佣金
			// .lookup({
			// 	from: "t3ds-account-log",
			// 	let: {
			// 		orderId: "$_id"
			// 	},
			// 	pipeline: $.pipeline()
			// 		.match(dbCmd.expr($.and([
			// 			$.eq(["$orderId", "$$orderId"]),
			// 			$.in(["$tradeType", [6]])
			// 		])))
			// 		.group({
			// 			_id: null,
			// 			income: $.sum("$income")
			// 		})
			// 		.done(),
			// 	as: "backBrokerageInfo"
			// })
			.lookup({
				from: "t3ds-refund-apply",
				let: {
					orderId: "$_id"
				},
				pipeline: $.pipeline()
					.match(dbCmd.expr($.and([
						$.eq(["$orderSn", "$$orderId"]),
						$.in(["$status", ["REFUNDING", "REFUNDED"]])
					])))
					.group({
						_id: null,
						count: $.sum("$count")
					})
					.done(),
				as: "refundInfos"
			})
			.project({
				brokerageInfo: "$brokerageInfo",
				// backBrokerageInfo: "$backBrokerageInfo",
				totalFee: "$total_fee",
				goodsId: "$items.goods_id",
				goodsName: "$items.goods_name",
				goodsThumb: "$items.goods_thumb",
				count: "$items.count",
				refundInfo: $.cond({
					if: $.gt([$.size("$refundInfos"), 0]),
					then: $.arrayElemAt(["$refundInfos", 0]),
					else: {
						count: 0
					}
				}),
				realSettlement: $.cond({
					if: $.eq(['$items.settle_flag', true]),
					then: 0,
					else: "$items.settlement_price"
				}),
				price: "$items.price"
			})
			.project({
				brokerageInfo: 1,
				// backBrokerageInfo: 1,
				totalFee: 1,
				goodsId: 1,
				goodsName: 1,
				goodsThumb: 1,
				count: $.subtract(["$count", "$refundInfo.count"]),
				refundFee: $.cond({
					if: $.eq(["$totalFee", 0]),
					then: 0,
					else: $.multiply(["$refundInfo.count", "$price"])
				}),
				settlement: $.multiply(["$realSettlement", $.subtract(["$count", "$refundInfo.count"])])
			})
			.lookup({
				from: "t3ds-mall-sku",
				let: {
					goodsId: "$goodsId"
				},
				pipeline: $.pipeline()
					.match(dbCmd.expr($.eq(["$goods_id", "$$goodsId"])))
					.group({
						_id: null,
						sellCount: $.sum("$sellCount"),
						stock: $.sum("$stock")
					})
					.done(),
				as: "sellInfo"
			})
			.limit(9999999)
			.end();
		let goodsDic = {}
		res.data.forEach(item => {
			let g = goodsDic[item.goodsId]
			if (!g) {
				g = {
					totalFee: 0,
					brokerage: 0,
					// backBrokerage: 0,
					settlement: 0,
					refundFee: 0,
					stock: 0,
					totalSellCount: 0,
					sellCount: 0,
					goodsId: '',
					goodsName: '',
					goodsThumb: ''
				}
				goodsDic[item.goodsId] = g
			}
			g.totalFee += item.totalFee
			g.sellCount += item.count
			if (item.sellInfo.length) {
				g.totalSellCount = item.sellInfo[0].sellCount
				g.stock = item.sellInfo[0].stock
			}
			item.brokerageInfo.forEach(b => {
				g.brokerage += b.income
			})
			// item.backBrokerageInfo.forEach(b => {
			// 	g.backBrokerage += (-b.income) // 退款income是负数
			// })
			g.settlement += item.settlement
			g.refundFee += item.refundFee
			g.goodsId = item.goodsId
			g.goodsName = item.goodsName
			g.goodsThumb = item.goodsThumb
		})
		var goodsList = Object.values(goodsDic)
		//统计总销量 (性能带优化)
		goodsIds = goodsList.map(item => {
			return item.goodsId
		})
		let sellInfoRes = await this.db.collection("t3ds-order").aggregate()
			.match({
				'items.goods_id': dbCmd.in(goodsIds),
				'status': dbCmd.gt(2).and(dbCmd.lt(10))
			})
			.unwind("$items")
			.lookup({
				from: "t3ds-refund-apply",
				let: {
					orderId: "$_id"
				},
				pipeline: $.pipeline()
					.match(dbCmd.expr($.and([
						$.eq(["$orderSn", "$$orderId"]),
						$.in(["$status", ["REFUNDING", "REFUNDED"]])
					])))
					.group({
						_id: null,
						count: $.sum("$count")
					})
					.done(),
				as: "refundInfos"
			})
			.project({
				goodsId: "$items.goods_id",
				count: "$items.count",
				refundInfo: $.cond({
					if: $.gt([$.size("$refundInfos"), 0]),
					then: $.arrayElemAt(["$refundInfos", 0]),
					else: {
						count: 0
					}
				})
			})
			.project({
				goodsId: 1,
				count: $.subtract(["$count", "$refundInfo.count"]),
			})
			.group({
				_id: "$goodsId",
				count: $.sum("$count")
			})
			.limit(9999999)
			.end();
		sellInfoRes.data.forEach(item => {
			goodsDic[item._id].totalSellCount = item.count
		})
		goodsList = Object.values(goodsDic)
		goodsList.forEach(item => {
			console.log('xxx', item.settlement, item.brokerage, item.refundFee)
			// item.profit = item.totalFee - item.settlement - item.brokerage - item.refundFee - item.backBrokerage
			item.profit = item.totalFee - item.settlement - item.brokerage - item.refundFee
			item.totalFee -= item.refundFee
			result.totalProfit += item.profit
			result.totalFee += item.totalFee
		})
		goodsList.sort((a, b) => {
			return b.profit - a.profit
		})
		
		result.list = goodsList;
		return result;
	}

	async getExchangeCodeGroupList({
		pageNum = 1,
		pageSize = 10,
		city
	}) {
		try {
			let result = {
				total: 0,
				list: []
			}
			let dbCmd = this.db.command
			var query = {}
			if (city) {
				query.city = city
			}
			let $ = this.db.command.aggregate
			if (pageNum == 1) {
				let totalRes = await this.db.collection("t3ds-goods-exchange")
					.aggregate()
					.group({
						_id: {
							batchNo: "$batchNo",
							goodsId: "$goodsId",
							skuId: "$skuId",
							salesman: "$salesman",
							salesmanPhone: "$salesmanPhone"
						}
					})
					.count('total')
					.end()
				if (!totalRes.data.length || !totalRes.data[0].total) {
					return result
				}
				result.total = totalRes.data[0].total
			}
			let res = await this.db.collection("t3ds-goods-exchange")
				.aggregate()
				.match(query)
				.group({
					_id: {
						batchNo: "$batchNo",
						goodsId: "$goodsId",
						skuId: "$skuId",
						salesman: "$salesman",
						salesmanPhone: "$salesmanPhone",
						settlementPrice: "$settlementPrice"
					},
					count: $.sum(1),
				})
				.skip(pageNum - 1)
				.limit(pageSize)
				.sort({
					'_id.batchNo': -1
				})
				.lookup({
					from: "t3ds-mall-goods",
					let: {
						goodsId: "$_id.goodsId"
					},
					pipeline: $.pipeline().match(dbCmd.expr($.eq(['$_id', '$$goodsId'])))
						.project({
							name: 1
						})
						.done(),
					as: "goods"
				})
				.lookup({
					from: "t3ds-mall-sku",
					let: {
						skuId: "$_id.skuId"
					},
					pipeline: $.pipeline().match(dbCmd.expr($.eq(['$_id', '$$skuId'])))
						.project({
							name: 1
						})
						.done(),
					as: "sku"
				})
				.end()
			result.list = res.data.map(item => {
				let t = Object.assign({}, item._id)
				t.count = item.count
				t.goodsName = item.goods[0] ? item.goods[0].name : ''
				t.skuName = item.sku[0] ? item.sku[0].name : ''
				return t
			})
			return result
		} catch (e) {
			throw e
		}
	}

	async createExchangeCode({
		goodsId,
		skuId,
		count,
		salesman,
		salesmanPhone,
		settlementPrice,
		city
	}) {
		let sku = await dbHelper.getById("t3ds-mall-sku", skuId)
		if (!sku) {
			throw new Error("规格不存在")
		}
		let batchNo = Date.now()
		for (var i = 0; i < count; i++) {
			await dbHelper.insert("t3ds-goods-exchange", {
				batchNo,
				goodsId,
				skuId,
				status: 'delivered',
				salesman,
				salesmanPhone,
				settlementPrice,
				city,
				createTime: Date.now()
			})
		}
	}

	async checkReachByLimitCount(memberId, sku) {
		try {
			let dbCmd = this.db.command
			let $ = dbCmd.aggregate
			let res = await this.db.collection("t3ds-order").aggregate()
				.match({
					user_id: memberId + '',
					'items.sku_id': sku._id,
					status: dbCmd.gte(1)
				})
				.unwind("$items")
				.group({
					_id: null,
					count: $.sum("$items.count")
				})
				.end()
			var buyCount = 0
			if (res.data.length) {
				buyCount = res.data[0].count
			}
			return buyCount >= sku.buy_limit_count
		} catch (e) {
			throw e
		}
	}

	async getGoodsDetail(id, userLocation, token) {
		try {
			const dbCmd = this.db.command
			let goods = await dbHelper.getById("t3ds-mall-goods", id)
			if (!goods) {
				return {
					code: 500,
					msg: "商品不存在"
				}
			}
			this.db.collection("t3ds-mall-goods").doc(id).update({
				hit_count: dbCmd.inc(1)
			})
			goods.hit_count = (goods.hit_count || 0) + 1
			if (goods.detail) {
				goods.detail = goods.detail.replace(/<img [^>]*src=['"]([^'"]+)[^>]*>/gi, function(match,
					capture) {
					return match.replace(/src=[\'\"]?([^\'\"]*)[\'\"]?/i, function(match2, capture2) {
						if (capture2.startsWith(CLOUDURL)) {
							return `src="${capture2}"`
						}
						return `src="${CLOUDURL}/imageLoader/?url=${encodeURIComponent(capture2)}"`
					})
				})
				goods.detail = goods.detail.replace(/url\(.+?\)/gi, function(match, capture) {
					return match.replace(
						/(http(s?):\/\/)?([A-Za-z0-9]+\.[A-Za-z0-9]+[\/=\?%\-&_~`@[\]\':+!]*([^<>\"\"\'])*)/gi,
						function(match2, capture2) {
							if (match2.startsWith(CLOUDURL)) {
								return match2
							}
							return `${CLOUDURL}/imageLoader/?url=${encodeURIComponent(match2)}`
						})
				})
			}
			// console.log("detail", goods.detail)
			let skuRes = await this.db.collection("t3ds-mall-sku").where({
				goods_id: goods._id,
				is_on_sale: true
			}).orderBy("order", "asc").orderBy("price", "asc").get();
			let skus = skuRes.data;
			let skuIdList = []
			skus.forEach(item => {
				skuIdList.push(item._id)
			})
			await this.syncSeckillStatus(skuIdList);
			if (skus.length) {
				//如果是分销商品，并且用户已登录
				let member
				if (token) {
					let payload = await uniID.checkToken(token)
					if (payload.code === 0) {
						member = payload.userInfo
						for (var i = 0; i < skus.length; i++) {
							let item = skus[i];
							if (item.buy_limit_count) {
								item.reachBuyLimitCount = await this.checkReachByLimitCount(member._id, item)
							} else {
								item.reachBuyLimitCount = false
							}
						}
						if (goods.distribution) {
							let gradeSetting = await dbHelper.getOne("t3ds-share-expert-grade", {
								value: member.shareGrade
							})
							for (var i = 0; i < skus.length; i++) {
								let item = skus[i]
								let profit = item.price - item.settlement_price;
								let shareReward = item.share_reward[gradeSetting.value + ""];
								if (shareReward == undefined || shareReward < 0) {
									item.shareReward = Math.round(gradeSetting.share_reward / 100 * profit /
										100) * 100;
								} else {
									item.shareReward = Math.round(shareReward / 100 * profit / 100) * 100;
								}
								if (item.share_reward2 == undefined || item.share_reward2 < 0) {
									item.shareReward2 = Math.round(gradeSetting.share_reward2 / 100 * profit /
										100) * 100;
								}
								if (gradeSetting.value !== 0) {
									let buyReward = item.self_buy_reward[gradeSetting.value + ''];
									if (buyReward == undefined || buyReward < 0) {
										item.buyReward = Math.round(gradeSetting.self_buy_reward / 100 *
											profit / 100) * 100;
									} else {
										item.buyReward = Math.round(buyReward / 100 * profit / 100) * 100
									}
								}
							}
						}
					}
				}
				// 将无库存的规格放后面
				let t = [];
				let t1 = [];
				for (var i = 0; i < skus.length; i++) {
					let item = skus[i];
					if (!member || !member.shareGrade) {
						if (item.purchaseNotes) {
							item.purchaseNotes = item.purchaseNotes.filter(note => {
								return !note.onlyExpert
							})
						}
						if (item.useNotes) {
							item.useNotes = item.useNotes.filter(note => {
								return !note.onlyExpert
							})
						}
						if (item.costNotes) {
							item.costNotes = item.costNotes.filter(note => {
								return !note.onlyExpert
							})
						}
						if (item.otherNotes) {
							item.otherNotes = item.otherNotes.filter(note => {
								return !note.onlyExpert
							})
						}
					}
					var sellCount = 0;
					if (item.sellCount) {
						sellCount += item.sellCount;
					}
					if (item.unrealSellCount) {
						sellCount += item.unrealSellCount;
					}
					item.sellCount = sellCount;
					delete item.unrealSellCount;
					delete item.settlement_price;
					delete item.self_buy_reward
					delete item.share_reward
					delete item.share_reward3
					delete item.share_reward_old
					let seckillsku = await this.db.collection("t3ds-mall-goods-seckill").where({
							skuId: item._id,
							status: 'underway'
						})
						.field({
							_id: true,
							price: true,
							settlementPrice: true
						})
						.get()
						if(seckillsku.data.length > 0) {
							item.seckillPrice = seckillsku.data[0].price
							item.seckillSettlementPrice = seckillsku.data[0].settlementPrice
						}
					if (item.stock > 0) {
						t.push(item);
					} else {
						t1.push(item);
					}
				}
				goods.skus = t.concat(t1);
			}
			// 将无库存的规格放后面
			// let t = [];
			// let t1 = [];
			// skus.forEach(item => {
			// 	if (item.stock > 0) {
			// 		t.push(item);
			// 	} else {
			// 		t1.push(item);
			// 	}
			// })
			// goods.skus = t.concat(t1);

			let stores;
			if (userLocation) {
				let $ = dbCmd.aggregate;
				let storeData = await this.db.collection("t3ds-store").aggregate()
					.geoNear({
						distanceField: 'distance',
						spherical: true,
						near: new this.db.Geo.Point(Number(userLocation.longitude), Number(userLocation
							.latitude)),
						query: {
							'_id': $.in(goods.store_ids)
						}
					})
					.project({
						introduction: 0,
						photos: 0,
					})
					.end();
				stores = storeData.data;
			} else {
				let storeData = await this.db.collection("t3ds-store").where({
						'_id': dbCmd.in(goods.store_ids)
					})
					.field({
						introduction: false,
						photos: false
					})
					.get();
				stores = storeData.data;
			}
			goods.stores = stores;

			// 商品推荐
			goods.recommendList = await this.getRecommendList(goods)

			return {
				code: 200,
				result: goods
			}
		} catch (e) {
			console.error(e)
			return {
				code: 500,
				msg: e.message
			}
		}
	}

	// 获取商品推荐
	async getRecommend(goods, categoryId) {
		const dbCmd = this.db.command
		const $ = dbCmd.aggregate

		const {
			coordinates: [longitude, latitude]
		} = JSON.parse(JSON.stringify(goods.stores[0].location))
		const goodsId = goods._id
		// console.log(JSON.parse(JSON.stringify(goods.stores[0].location)));

		let res = await this.db.collection('t3ds-store').aggregate()
			.geoNear({ // 由近到远输出该商品所在门店周边的门店
				near: new this.db.Geo.Point(longitude, latitude),
				spherical: true,
				distanceField: 'distance'
			})
			.lookup({ // 生成goods字段存放该门店下的所有商品
				from: 't3ds-mall-goods',
				let: {
					storeId: '$_id'
				},
				pipeline: $.pipeline()
					.match(dbCmd.expr($.in(['$$storeId', '$store_ids'])))
					.done(),
				as: 'goods'
			})
			.unwind("$goods") // 根据商品拆分
			.match({ // 查找同类型、不同商品、已上架的商品
				'goods.category_id': categoryId,
				'goods._id': dbCmd.neq(goodsId),
				'goods.is_on_sale': true
				// 'region.city.value': '4201'
			})
			.sort({ // 根据 最低价从低到高排序 && 总销量从高到低排序
				'goods.price': 1,
				'goods.totalSellCount': -1
			})
			.limit(2) // 输出两条记录
			.project({ // 返回指定字段
				_id: '$goods._id',
				thumb: '$goods.thumb',
				name: '$goods.name',
				price: '$goods.price',
				market_price: '$goods.market_price',
				discountsForVip: '$goods.discountsForVip',
				category_id: '$goods.category_id'
			})
			.end()

		// console.log(res.data);
		return res.data
	}

	// 获取商品推荐列表
	async getRecommendList(goods) {
		let goodsList = []
		let categoryList = await this.db.collection('t3ds-mall-categories').where({
			parentId: "28ee4e3e607d191810778fe541f0cff2"
		}).get()
		try {
			// 不同类型商品
			for (let item of categoryList.data) {
				if (goods.category_id !== item._id) {
					let res = await this.getRecommend(goods, item._id)
					if (res) {
						goodsList = goodsList.concat(res)
					}
				}
			}
			// 同类型商品放最后
			let res = await this.getRecommend(goods, goods.category_id)
			goodsList = goodsList.concat(res)

			return goodsList
		} catch (e) {
			throw e
		}
	}

	// 删除商品
	async delGoods(goodsId) {
		try {
			let db = uniCloud.database()
			await db.collection('t3ds-mall-sku').where({
				goods_id: goodsId
			}).remove()
			await db.collection('t3ds-mall-goods').doc(goodsId).remove()
			return {
				code: 200,
				result: '删除成功'
			}
		} catch (e) {
			return {
				code: 500,
				msg: e.message
			}
		}
	}
	
	//添加限时秒杀商品(修改)
	async createSeckillGoods({params}) {
		let sku = await dbHelper.getById("t3ds-mall-sku", params.skuId)
		if (!sku) {
			throw new Error("规格不存在")
		}
		//秒杀库存不能超过总库存
		if(sku.stock < params.stock) {
			throw new Error("后台库存不足，无法创建")
		}
		//秒杀售价不能超过原售价
		if(sku.price < params.price) {
			throw new Error("秒杀售价过高，无法创建")
		}
		//let transaction = await this.db.startTransaction()
		try{
			if(params._id) {
				//修改规格库存
				await dbHelper.update("t3ds-mall-goods-seckill", params)
			}else {
				await dbHelper.insert("t3ds-mall-goods-seckill", params)
			}
			//await dbHelper.insert("t3ds-mall-goods-seckill", params)
			return {
				code: 200,
				result: '操作成功'
			}
			//await transaction.commit()
		}catch(e){
			//await transaction.rollback()
			return {
				code: 500,
				msg: e.message
			}
		}
	}
	
	//（已弃用）开始限时秒杀任务
	async seckillTask(seckillId) {
		let seckillGood = await dbHelper.getById("t3ds-mall-goods-seckill", seckillId)
		if (!seckillGood) {
			throw new Error("该秒杀商品不存在")
		}
		if(seckillGood.addDate < Date.now()) {
			throw new Error("该秒杀商品的上架时间还未到")
		}
		if(seckillGood.residueStock < 1) {
			throw new Error("该秒杀商品已售罄")
		}
		if(seckillGood.endDate < Date.now()) {
			throw new Error("该秒杀商品已下架")
		}
		try{
			await dbHelper.update("t3ds-mall-sku", {
				_id: seckillGood.skuId,
				stock: stock - seckillGood.stock
			})
			return {
				code: 200,
				result: '上架成功'
			}
		}catch(e){
			return {
				code: 500,
				msg: e.message
			}
		}
	}
	
	//秒杀倒计时结束后调用
	async getNextTime(skuIdList) {
		await this.syncSeckillStatus(skuIdList);
		try{
			for(let i = 0 ; i < skuIdList.length ;i++) {
				let sku = await this.db.collection("t3ds-mall-sku").where({
					'_id': skuIdList[i],
					'is_on_sale': true,
					'is_on_seckill': true
				})
				.field({
					seckill_status: true,
					gapTime: true,
					buyTime: true
				})
				.get()
				let tempSku = sku.data[0]
				let res = {}
				if(tempSku) {
					res._id = tempSku._id
					if(tempSku.seckill_status == 0) {
						//售罄
						res.nextTime = (tempSku.gapTime - tempSku.buyTime) * 60
					}else if(tempSku.seckill_status == 1) {
						//售卖中
						res.nextTime = tempSku.buyTime * 60
					}
				}else {
					res._id = skuIdList[i]
				}
				skuIdList[i] = res
			}
			return skuIdList
		}catch(e){
			throw e
		}
	}
	
	//秒杀规格校验
	async syncSeckillStatus(skuIdList) {
		try{
			//let skuList = []
			for(let i = 0 ; i < skuIdList.length ;i++) {
				let sku = await dbHelper.getById("t3ds-mall-sku", skuIdList[i])
				if(sku) {
					if(sku.is_on_seckill && sku.stock && sku.is_on_sale) {
						//当前时间
						//let nowTime = now().format("YYYY-MM-DD HH:mm:ss")
						//转换数据库每天活动开始时间格式
						// let tempTime = moment(sku.startDate).cnZone().format("YYYY-MM-DD HH:mm:ss")
						//当天第一次秒杀时间
						let oneTime = moment(sku.startDate).cnZone().year(now().year())
									.month(now().month())
									.date(now().date())
									.toDate().getTime();
						//转换数据库每天活动结束时间格式
						// let temp2Time = moment(sku.endDate).cnZone().format("YYYY-MM-DD HH:mm:ss")
						//当天秒杀结束时间
						let twoTime = moment(sku.endDate).cnZone().year(now().year())
									.month(now().month())
									.date(now().date())
									.toDate().getTime();
						//console.log("rrr",twoTime)
						//未到上架时间
						if(Date.now() < sku.upDate) {
							await dbHelper.update("t3ds-mall-sku", {
								_id: sku._id,
								is_on_sale: false,
								amountNow: 0,
								startNextDate: sku.upDate,
							})
						}else if(sku.upDate < Date.now() && Date.now() < sku.downDate) {
							//秒杀中
							//当天秒杀未开始
							if(Date.now() < oneTime) {
								await dbHelper.update("t3ds-mall-sku", {
									_id: sku._id,
									seckill_status: 0,
									startNextDate: oneTime,
									amountNow: 0
								})
							}else if(Date.now() > twoTime) {
								//当天秒杀已结束
								let res = moment(oneTime).cnZone().add(1, 'days').toDate().getTime()
								await dbHelper.update("t3ds-mall-sku", {
									_id: sku._id,
									seckill_status: 0,
									startNextDate: res,
									amountNow: 0
								})
							}else {
								//当天已秒杀次数
								let seckillCount = parseInt((Date.now() - oneTime)/1000/60/sku.gapTime)
								//此次秒杀开始时间
								let startNowDate = moment(oneTime).cnZone().add(sku.gapTime*seckillCount, 'minute')
												.toDate().getTime()
								//此次秒杀结束时间
								let endNowDate = moment(startNowDate).cnZone().add(sku.buyTime, 'minute').toDate().getTime()
								//下次秒杀开始时间
								let startNextDate = moment(startNowDate).cnZone().add(sku.gapTime, 'minute').toDate().getTime()
								//console.log("qqq",startNowDate)
								//console.log("www",endNowDate)
								//console.log("eee",startNextDate)
								//满足条件开始秒杀任务
								if(startNowDate < Date.now() && Date.now() < endNowDate) {
									//console.log("bbb",startNowDate)
									//console.log("nnn",endNowDate)
									//console.log("nnn",Date.now())
									if(endNowDate != sku.endNowDate) {
										await dbHelper.update("t3ds-mall-sku", {
											_id: sku._id,
											seckill_status: 1,
											amountNow: sku.amount,
											endNowDate: endNowDate
										})
										console.log("开始秒杀")
									}else if(sku.seckill_status == 0 && startNextDate != sku.startNextDate) {
										await dbHelper.update("t3ds-mall-sku", {
											_id: sku._id,
											seckill_status: 1,
											amountNow: sku.amount,
											endNowDate: endNowDate
										})
										console.log("开始秒杀")
									}else if(sku.amountNow <= 0) {
										//提前售罄
										await dbHelper.update("t3ds-mall-sku", {
											_id: sku._id,
											seckill_status: 0,
											amountNow: 0,
											startNextDate: startNextDate
										})
									}else {
										console.log("正在售卖")
									}
								}else {
									//校验无法出售的秒杀规格（时间已过）
									if(endNowDate < Date.now() && Date.now() < startNextDate && startNextDate != sku.startNextDate) {
										await dbHelper.update("t3ds-mall-sku", {
											_id: sku._id,
											seckill_status: 0,
											amountNow: 0,
											startNextDate: startNextDate
										})
										console.log("结束秒杀")
									}else {
										console.log("已经结束")
									}
								}
							}
						}else {
							//规格下架时间已过
							await dbHelper.update("t3ds-mall-sku", {
								_id: sku._id,
								is_on_sale: false,
								amountNow: 0
							})
						}
					}
					//skuList.push(sku)
				}
			}
			// return {
			// 	code: 200,
			// 	result:skuList
			// }
		}catch(e){
			throw e;
			// return {
			// 	code: 500,
			// 	msg: e.message
			// }
		}
	}
	
	//计算当前用户购买商品的返利
	async getGoodRebate(goodsList,token) {
		try {
			let payload = await uniID.checkToken(token)
			if (payload.code === 0) {
				let member = payload.userInfo
				let gradeSetting = await dbHelper.getOne("t3ds-share-expert-grade", {
					value: member.shareGrade
				})
				goodsList.forEach(goods => {
					if (goods.distribution) {
						var maxShareReward = 0
						var maxShareReward2 = 0
						var maxBuyReward = 0
						goods.skus.forEach(sku => {
							let profit = sku.price - sku.settlement_price;
							let shareReward = sku.share_reward[gradeSetting.value + ""];
							if (shareReward == undefined || shareReward < 0) {
								sku.shareReward = Math.round(gradeSetting.share_reward /
									100 * profit /
									100) * 100;
							} else {
								sku.shareReward = Math.round(shareReward / 100 *
									profit / 100) * 100;
							}
							maxShareReward = Math.max(maxShareReward, sku.shareReward)
							if (sku.share_reward2 == undefined || sku.share_reward2 <
								0) {
								sku.shareReward2 = Math.round(gradeSetting
									.share_reward2 / 100 * profit /
									100) * 100;
							}
							maxShareReward2 = Math.max(maxShareReward2, sku
								.shareReward2)
							if (gradeSetting.value !== 0) {
								let buyReward = sku.self_buy_reward[gradeSetting.value +
									''];
								if (buyReward == undefined || buyReward < 0) {
									sku.buyReward = Math.round(gradeSetting
										.self_buy_reward / 100 *
										profit / 100) * 100;
								} else {
									sku.buyReward = Math.round(buyReward / 100 *
										profit / 100) * 100
								}
								maxBuyReward = Math.max(maxBuyReward, sku.buyReward)
							}
						})
						Object.assign(goods.sellInfo, {
							maxShareReward,
							maxShareReward2,
							maxBuyReward
						})
					}
				})
			}
			return goodsList
		} catch (e) {
			throw e;
		}
	}
	
	async syncHomeModuleCache(city) {
		//模块商品列表
		let dbCmd = this.db.command
		let $ = dbCmd.aggregate
		let res = await this.db.collection('t3ds-mall-home-module')
			.aggregate()
			.match({
				isOnSell: true,
				city
			})
			.lookup({
				from: "t3ds-mall-goods",
				let: {
					moduleId: '$_id'
				},
				pipeline: $.pipeline()
					.match(dbCmd.expr($.and([
							$.in(['$$moduleId', '$module_ids']),
							$.eq(['$is_on_sale', true])
						])
					))
					.lookup({
						from: "t3ds-mall-sku",
						let: {
							goodsId: '$_id'
						},
						pipeline: $.pipeline()
							.match(dbCmd.expr($.and([
									$.eq(['$goods_id', '$$goodsId']),
									$.eq(['$is_on_sale', true])
								])
							))
							.sort({
								price: 1
							})
							.project({
								price: 1,
								self_buy_reward: 1,
								settlement_price: 1,
								share_reward: 1,
								share_reward3: 1,
								share_reward_old: 1,
								stock: 1,
								unrealSellCount: 1,
								sellCount: 1,
								market_price: 1,
								is_on_seckill: 1,
								seckill_status: 1,
								endNowDate: 1,
								startNextDate: 1,
								upDate: 1,
								downDate: 1,
								startDate: 1,
								endDate: 1,
								gapTime: 1,
								buyTime: 1,
								amount: 1,
								amountNow: 1,
							})
							.done(),
						as: 'skus'
					})
					.done(),
				as: 'goods'
			})
			.sort({
				order_no: 1
			})
			.end()
		// for (var i = 0; i < res.data.length; i++) {
		// 	let m = res.data[i]
		// 	let goodsRes = await this.db.collection('t3ds-mall-goods')
		// 		.aggregate()
		// 		.match({
		// 			module_ids: dbCmd.all([m._id])
		// 		})
		// 		.lookup({
		// 			from: "t3ds-mall-sku",
		// 			let: {
		// 				goodsId: '$_id'
		// 			},
		// 			pipeline: $.pipeline()
		// 				.match(dbCmd.expr($.and([
		// 						$.eq(['$goods_id', '$$goodsId']),
		// 						$.eq(['$is_on_sale', true])
		// 					])
		// 				))
		// 				.sort({
		// 					price: 1
		// 				})
		// 				.project({
		// 					price: 1,
		// 					self_buy_reward: 1,
		// 					settlement_price: 1,
		// 					share_reward: 1,
		// 					share_reward3: 1,
		// 					share_reward_old: 1,
		// 					stock: 1,
		// 					unrealSellCount: 1,
		// 					sellCount: 1,
		// 					market_price: 1,
		// 					is_on_seckill: 1,
		// 					seckill_status: 1,
		// 					endNowDate: 1,
		// 					startNextDate: 1,
		// 					upDate: 1,
		// 					downDate: 1,
		// 					startDate: 1,
		// 					endDate: 1,
		// 					gapTime: 1,
		// 					buyTime: 1,
		// 					amount: 1,
		// 					amountNow: 1,
		// 				})
		// 				.done(),
		// 			as: 'skus'
		// 		})
		// 		// .sort({
		// 		// 	order_no: 1
		// 		// })
		// 		.end()
		// 	m.goodsList = goodsRes.data
		// }
		console.log('moduleList', res, city)
		let key = consts.redisKeys.keyModule + city
		if (redis.exists(key)) {
			await redis.del(key)
		}
		res.data.forEach(async item => {
			await redis.rpush(key, JSON.stringify(item))
		})
	}
	
	//无moduleId获取首页模块商品(有moduleId获取当前模块商品列表)
	async getModuleList({
		moduleId,
		pageNum = 1,
		pageSize = 10,
		city = "4201",
		userLocation,
		token,
		filter,
		order,
		keyword
	}) {
		const db = uniCloud.database()
		const dbCmd = db.command
		try {
			await this.syncGoodsStatus();
			if(moduleId) {
				let sort1 = {};
				//获取当前模块的商品列表
				let query1 = {
					"is_on_sale": true,
					"module_ids": dbCmd.all([moduleId]),
				}
				if (filter) {
					if (filter.categoryId) {
						query1['category_id'] = filter.categoryId;
					}
					if (filter.displayOnHome) {
						query1['display_on_home'] = filter.displayOnHome;
					}
				}
				if (order) {
					if (order.hitCount) {
						sort1['hit_count'] = order.hitCount === "asc" ? 1 : -1;
					}
					if (order.price) {
						sort1['sellInfo.price'] = order.price === "asc" ? 1 : -1;
					}
					if (order.sales) {
						sort1['sellInfo.totalSellCount'] = order.sales === "asc" ? 1 : -1
					}
					if (order.orderNo) {
						sort1['order_no'] = order.orderNo === "asc" ? 1 : -1;
					}
				}
				if (!Object.keys(sort1).length && (!order || !order.distance)) {
					sort1.update_time = -1;
					sort1.create_time = -1;
				}
				if (keyword) {
					query1['name'] = new RegExp(`${keyword}+`, 'i');
				}
				let goodsList = await this.getList(query1, sort1, city, pageNum, pageSize, userLocation);
				if (token) {
					goodsList = await this.getGoodRebate(goodsList,token)
				}
				return goodsList
			}else {
				//获取首页模块的商品列表
				//获取当前城市的上架模块
				// let moduleList = await dbHelper.getList("t3ds-mall-home-module", {
				// 	city: city,
				// 	isOnSell: true
				// });
				// for(let i = 0 ; i < moduleList.length ;i++) {
				// 	let query2 = {
				// 		"is_on_sale": true,
				// 		"display_on_home": true,
				// 		"module_ids": dbCmd.all([moduleList[i]._id]),
				// 	}
				// 	let sort2 = {order_no: 1};
				// 	let goodsList = await this.getList(query2, sort2, city, 1, 99, userLocation);
				// 	if (token) {
				// 		goodsList = await this.getGoodRebate(goodsList,token)
				// 	}
				// 	goodsList.forEach(goods => {
				// 		delete goods.skus
				// 	})
				// 	moduleList[i].goodsList = goodsList
				// }
				let moduleList = await dbHelper.getPage("t3ds-mall-home-module", pageNum, 1, {
						city: city,
						isOnSell: true
				});
				if (!moduleList.list.length) {
					return moduleList
				}
				let tempValue = moduleList.list[0]
				let query2 = {
					"is_on_sale": true,
					"display_on_home": true,
					"module_ids": dbCmd.all([tempValue._id]),
				}
				let sort2 = {order_no: 1};
				let goodsList = await this.getList(query2, sort2, city, 1, 99, userLocation);
				if (token) {
					goodsList = await this.getGoodRebate(goodsList,token)
				}
				goodsList.forEach(goods => {
					delete goods.skus
				})
				tempValue.goodsList = goodsList
				return moduleList
			}
		} catch (e) {
			console.error(e)
			throw e
		}
	}
	
	//获取首页的上新和售罄商品
	async getNewGoodsList({
		city = "4201",
		userLocation,
		token
	}) {
		const db = uniCloud.database()
		const dbCmd = db.command
		try {
			await this.syncGoodsStatus();
			let result = {}
			//上新
			let query1 = {
				"is_on_sale": true,
				"is_new": true,
				"new_down_deadline": dbCmd.gt(Date.now())
			}
			let sort = {order_no: 1};
			let newGoodList = await this.getList(query1, sort, city, 1, 99, userLocation);
			result.newGoodList = newGoodList
			//所有已上架的限时抢购的商品（售卖时间不足3天）
			let threeTime = moment().tz("Asia/Shanghai").add(3, 'days').hour(
				23).minute(59).second(59).toDate().getTime()
			let query2 = {
				"is_on_sale": true,
				"is_time_limited": true,
				"sale_deadline": dbCmd.gt(Date.now()),
				"sale_deadline": dbCmd.lt(threeTime)
			}
			let saleGoodList = await this.getList(query2, sort, city, 1, 99, userLocation);
			//库存不足百分之20的上架商品
			let query3 = {
				"is_on_sale": true,
				"is_time_limited": false
			}
			let countList = await this.getList(query3, sort, city, 1, 99, userLocation);
			for(let i = 0 ; i < countList.length ;i++) {
				let res = countList[i].sellInfo.totalSellCount/countList[i].sellInfo.totalStock
				if(res >= 0.8) {
					saleGoodList.push(countList[i])
				}
			}
			if (token) {
				newGoodList = await this.getGoodRebate(newGoodList,token)
				saleGoodList = await this.getGoodRebate(saleGoodList,token)
			}
			result.saleEndGoodList = saleGoodList
			return result
		} catch (e) {
			console.error(e)
			throw e
		}
	}
	
	//获取限时秒杀商品
	async getSeckillGoodsList({
		city = "4201",
		userLocation,
		token
	}) {
		const db = uniCloud.database()
		const dbCmd = db.command
		try {
			//await this.syncGoodsStatus();
			let goodsIdList = await this.db.collection("t3ds-mall-sku").where({
				'is_on_seckill': true,
				'is_on_sale': true
			})
			.field({
				goods_id: true,
			})
			.get()
			let skuIdList = []
			goodsIdList.data.forEach(item => {
				skuIdList.push(item._id)
			})
			await this.syncSeckillStatus(skuIdList);
			let result = []
			for(var n = 0; n < goodsIdList.data.length; n++) {
				let query = {
					"is_on_sale": true,
					"display_on_home": true,
					"_id": goodsIdList.data[n].goods_id
				}
				let sort = {order_no: 1};
				let temp = await this.getList(query, sort, city, 1, 1, userLocation);
				if(temp.length != 0) {
					if (token) {
						temp = await this.getGoodRebate(temp,token)
					}
					result.push(temp[0])
				}
			}
			return result
		} catch (e) {
			console.error(e)
			throw e
		}
	}
	
	// //获取首页轮播图
	async getHomeImageList() {
		try {
			let imageList = await this.db.collection("t3ds-mall-home-image")
				.where({
					'isOnSell': true
				})
				.orderBy("order_no", "asc")
				.get();
			return imageList.data
		} catch (e) {
			throw e
		}
	}
	
	//通过规格ID获取该规格的所有主题信息
	async getThemeDetail({
		skuId,
		themeId
	}) {
		try {
			let params = {
				sku_id: skuId,
			}
			if(themeId) {
				params._id = themeId
			}
			let themeList = await dbHelper.getList("t3ds-theme-config", params);
			return themeList
		} catch (e) {
			console.error(e)
			throw e
		}
	}
	
	//通过规格ID获取商品的图片名字价格
	async getPhotoAndPrice({
		skuId
	}) {
		try {
			let goodsDetail = {}
			let sku = await this.db.collection("t3ds-mall-sku").where({
				'_id': skuId
			})
			.field({
				price: true,
				goods_id: true
			})
			.get()
			goodsDetail.price = sku.data[0].price
			let goodsId = sku.data[0].goods_id
			let good = await this.db.collection("t3ds-mall-goods").where({
				'_id': goodsId
			})
			.field({
				name: true,
				thumb: true
			})
			.get()
			goodsDetail.name = good.data[0].name
			goodsDetail.thumb = good.data[0].thumb
			return goodsDetail
		} catch (e) {
			console.error(e)
			throw e
		}
	}
}
